import 'dart:convert';
import 'dart:developer';
import 'dart:io';

import 'package:meeting_note/tencent/cos/config.dart';
import 'package:tencentcloud_cos_sdk_plugin/cos_transfer_manger.dart';
import 'package:tencentcloud_cos_sdk_plugin/fetch_credentials.dart';
import 'package:tencentcloud_cos_sdk_plugin/pigeon.dart';
import 'package:tencentcloud_cos_sdk_plugin/cos.dart';
import 'package:tencentcloud_cos_sdk_plugin/transfer_task.dart';

// //await Cos().initWithSessionCredential(FetchCredentials());
// class FetchCredentials implements IFetchCredentials {
//   @override
//   Future<SessionQCloudCredentials> fetchSessionCredentials() async {
//     // 首先从您的临时密钥服务器获取包含了密钥信息的响应，例如：
//     var httpClient = HttpClient();
//     try {
//       // 临时密钥服务器 url，临时密钥生成服务请参考 https://cloud.tencent.com/document/product/436/14048
//       var stsUrl = "http://stsservice.com/sts";
//       var request = await httpClient.getUrl(Uri.parse(stsUrl));
//       var response = await request.close();
//       if (response.statusCode == HttpStatus.OK) {
//         var json = await response.transform(utf8.decoder).join();
//         log(json);

//         // 然后解析响应，获取临时密钥信息
//         var data = jsonDecode(json);
//         // 最后返回临时密钥信息对象
//         return SessionQCloudCredentials(
//             secretId: data['credentials']['tmpSecretId'], // 临时密钥 SecretId
//             secretKey: data['credentials']['tmpSecretKey'], // 临时密钥 SecretKey
//             token: data['credentials']['sessionToken'], // 临时密钥 Token
//             startTime: data['startTime'], //临时密钥有效起始时间，单位是秒
//             expiredTime: data['expiredTime'] //临时密钥有效截止时间戳，单位是秒
//             );
//       } else {
//         throw ArgumentError();
//       }
//     } catch (exception) {
//       throw ArgumentError();
//     }
//   }
// }

// //await Cos().initWithScopeLimitCredential(FetchScopeLimitCredentials());
// class FetchScopeLimitCredentials implements IFetchScopeLimitCredentials {
//   @override
//   Future<SessionQCloudCredentials> fetchScopeLimitCredentials(
//       List<STSCredentialScope?> stsCredentialScopes) async {
//     // 首先从您的临时密钥服务器获取包含了密钥信息的响应，例如：
//     var httpClient = HttpClient();
//     try {
//       // 临时密钥服务器 url，临时密钥生成服务请参考 https://cloud.tencent.com/document/product/436/14048
//       // 范围限制的临时密钥服务请参考：https://cloud.tencent.com/document/product/436/31923
//       var stsUrl = "https://stsservice.com/sts/scope";
//       var request = await httpClient.postUrl(Uri.parse(stsUrl));
//       request.headers.contentType = ContentType.json;
//       // 将范围实体列表转换为post body中的json
//       final body = jsonifyScopes(stsCredentialScopes);
//       log(body);
//       request.write(body);

//       var response = await request.close();
//       if (response.statusCode == HttpStatus.OK) {
//         var json = await response.transform(utf8.decoder).join();
//         log(json);
//         // 然后解析响应，获取临时密钥信息
//         var data = jsonDecode(json);
//         // 最后返回临时密钥信息对象
//         return SessionQCloudCredentials(
//             secretId: data['credentials']['tmpSecretId'],
//             secretKey: data['credentials']['tmpSecretKey'],
//             token: data['credentials']['sessionToken'],
//             startTime: data['startTime'],
//             expiredTime: data['expiredTime']);
//       } else {
//         throw ArgumentError();
//       }
//     } catch (exception) {
//       log(exception.toString());
//       throw ArgumentError();
//     }
//   }

//   // 将范围实体列表转换为json
//   String jsonifyScopes(List<STSCredentialScope?> scopes) {
//     List<Map<String, String?>> scopeList = [];
//     for (STSCredentialScope? scope in scopes) {
//       if (scope != null) {
//         Map<String, String?> scopeMap = {
//           'action': scope.action,
//           'bucket': scope.bucket,
//           'prefix': scope.prefix,
//           'region': scope.region,
//         };
//         scopeList.add(scopeMap);
//       }
//     }
//     return jsonEncode(scopeList);
//   }
// }

// void forceInvalidationCredential() async {
//   await Cos().forceInvalidationCredential();
// }

void register() async {
  //FIXME: 由于该方式存在泄露密钥的风险，请务必在上线前替换为临时密钥的方式。
  await Cos().initWithPlainSecret(CosConfig.secretId, CosConfig.secretKey);

  // 存储桶所在地域简称，例如广州地区是 ap-guangzhou
  // 创建 CosXmlServiceConfig 对象，根据需要修改默认的配置参数
  CosXmlServiceConfig serviceConfig = CosXmlServiceConfig(
    region: CosConfig.region,
    isDebuggable: true,
    isHttps: true,
  );
  // 注册默认 COS Service
  await Cos().registerDefaultService(serviceConfig);

  // 创建 TransferConfig 对象，根据需要修改默认的配置参数
  // TransferConfig 可以设置智能分块阈值 默认对大于或等于2M的文件自动进行分块上传，可以通过如下代码修改分块阈值
  TransferConfig transferConfig = TransferConfig(
    forceSimpleUpload: false,
    enableVerification: true,
    divisionForUpload: 2097152, // 设置大于等于 2M 的文件进行分块上传
    sliceSizeForUpload: 1048576, //设置默认分块大小为 1M
  );
  // 注册默认 COS TransferManger
  await Cos().registerDefaultTransferManger(serviceConfig, transferConfig);

  // // 也可以通过 registerService 和 registerTransferManger 注册其他实例， 用于后续调用
  // // 一般用 region 作为注册的 key
  //   String newRegion = "NEW_COS_REGION";
  //   await Cos().registerService(newRegion, serviceConfig..region = newRegion);
  //   await Cos().registerTransferManger(
  //       newRegion, serviceConfig..region = newRegion, transferConfig);
}

Future<TransferTask> putAudioFile({
  required String cosPath,
  required String srcPath,
}) async {
  String bucket = CosConfig.bucket;
  // 获取 TransferManager
  CosTransferManger transferManager = Cos().getDefaultTransferManger();

  String? uploadId;

  // 上传成功回调
  successCallBack(Map<String?, String?>? header, CosXmlResult? result) {
    // todo 上传成功后的逻辑
    // 由于 log 方法的参数需要是 String 类型，而 result?.toString() 可能为 null，因此使用空值合并运算符 ?? 确保传入的值不为 null
    log(result?.toString() ?? 'result is null');
  }

  //上传失败回调
  failCallBack(clientException, serviceException) {
    // todo 上传失败后的逻辑
    if (clientException != null) {
      log(clientException.toString());
    }
    if (serviceException != null) {
      log(serviceException.toString());
    }
  }

  //上传状态回调, 可以查看任务过程
  stateCallback(state) {
    // todo notify transfer state
    log(state.toString());
  }

  //上传进度回调
  progressCallBack(complete, target) {
    // todo Do something to update progress...
    log('$complete/$target');
  }

  //初始化分块完成回调
  initMultipleUploadCallback(String bucket, String cosKey, String uploadId) {
    //用于下次续传上传的 uploadId
    uploadId = uploadId;
  }

  //开始上传
  TransferTask transferTask = await transferManager.upload(
    bucket,
    cosPath,
    filePath: srcPath,
    uploadId: uploadId,
    resultListener: ResultListener(successCallBack, failCallBack),
    stateCallback: stateCallback,
    progressCallBack: progressCallBack,
    initMultipleUploadCallback: initMultipleUploadCallback,
  );
  return transferTask;
}

Future<TransferTask> getAudioFile({
  required String bucket,
  required String cosPath,
  required String dstPath,
}) async {
  // 获取 TransferManager
  CosTransferManger transferManager = Cos().getDefaultTransferManger();
  //CosTransferManger transferManager = Cos().getTransferManger("newRegion");
  // 存储桶名称，由 bucketname-appid 组成，appid 必须填入，可以在 COS 控制台查看存储桶名称。 https://console.cloud.tencent.com/cos5/bucket
  // 下载成功回调
  successCallBack(Map<String?, String?>? header, CosXmlResult? result) {
    // todo 下载成功后的逻辑
    log(result?.toString() ?? 'result is null');
  }

  //下载失败回调
  failCallBack(clientException, serviceException) {
    // todo 下载失败后的逻辑
    if (clientException != null) {
      log(clientException);
    }
    if (serviceException != null) {
      log((serviceException as CosXmlServiceException).details ?? "");
    }
  }

  //下载状态回调, 可以查看任务过程
  stateCallback(state) {
    // todo notify transfer state
    log(state.toString());
  }

  //下载进度回调
  progressCallBack(complete, target) {
    // todo Do something to download progress...
    log('$complete/$target');
  }

  //开始下载
  TransferTask transferTask = await transferManager.download(
    bucket,
    cosPath,
    dstPath,
    resultListener: ResultListener(successCallBack, failCallBack),
    stateCallback: stateCallback,
    progressCallBack: progressCallBack,
  );
  return transferTask;
}

Future<void> deleteAudioFile({
  required String region,
  required String bucket,
  required String cosPath,
}) async {
  try {
    await Cos().getDefaultService().deleteObject(
      bucket,
      cosPath,
      region: region,
    );
  } catch (e) {
    // 失败后会抛异常 根据异常进行业务处理
    log(e.toString());
  }
  return;
}

/// 生成对象下载预签名链接
///
/// [bucket] 存储桶名称，格式为 BucketName-APPID
/// [cosPath] 对象在存储桶中的唯一标识
/// [signValidTime] 签名有效期（秒），默认为 SDK 默认值
/// [signHost] 是否签入 Header Host
/// [parameters] HTTP 请求参数
Future<String> generatePresignedUrl({
  required String bucket,
  required String cosPath,
  int? signValidTime,
  bool? signHost,
  Map<String, String>? parameters,
}) async {
  try {
    // 调用 SDK 生成预签名链接
    return await Cos().getDefaultService().getPresignedUrl(
      bucket,
      cosPath,
      signValidTime: signValidTime,
      signHost: signHost,
      parameters: parameters,
    );
  } catch (e) {
    // 失败后记录日志并重新抛出异常
    log('生成预签名链接失败: ${e.toString()}');
    rethrow;
  }
}
